﻿
Public Class randomrun

    Public Delegate Sub randomrunAction()
    Public Delegate Sub randomrunAction2(ByVal obj As Object)

    Public Class info
        Public percent As Double = 0
        Public invoke As randomrunAction = Nothing
        Public invoke2 As randomrunAction2 = Nothing

        Private Sub initial(ByVal per As Double, ByVal action As randomrunAction)
            percent = per
            invoke = action
        End Sub

        Private Sub initial(ByVal per As Double, ByVal action2 As randomrunAction2)
            percent = per
            invoke2 = action2
        End Sub

        Public Sub New(ByVal per As Double, ByVal action As randomrunAction)
            initial(per, action)
        End Sub

        Public Sub New(ByVal action As randomrunAction, ByVal per As Double)
            initial(per, action)
        End Sub

        Public Sub New(ByVal per As Double, ByVal action As randomrunAction2)
            initial(per, action)
        End Sub

        Public Sub New(ByVal action As randomrunAction2, ByVal per As Double)
            initial(per, action)
        End Sub
    End Class

    Public Shared Sub invoke(ByVal obj As Object, ByVal ParamArray p() As info)
        'p={action0, percent0, action1, percent1 ...}
        assert(Not p Is Nothing AndAlso p.Length > 0, "ParamArray is not as expected.")
        Dim i As Int64
        Dim j As Double = rnd(0, 1)
        For i = 0 To p.Length() - 1
            If j < p(i).percent OrElse i = p.Length() - 1 Then
                If Not p(i).invoke Is Nothing Then
                    p(i).invoke()
                Else
                    p(i).invoke2(obj)
                End If
                Exit For
            Else
                j -= p(i).percent
            End If
        Next
    End Sub

    Public Shared Sub invoke(ByVal ParamArray p() As info)
        invoke(CType(Nothing, Object), p)
    End Sub

    Public Shared Sub invoke(ByVal roundcount As Int64, ByVal obj As Object, ByVal ParamArray p() As info)
        While roundcount > 0
            invoke(obj, p)
            roundcount -= 1
        End While
    End Sub

    Public Shared Sub invoke(ByVal roundcount As Int64, ByVal ParamArray p() As info)
        invoke(roundcount, CType(Nothing, Object), p)
    End Sub
End Class
